package com.ibp.other;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.Socket;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ibp.dao.IbpEventLogDataMapper;
import com.ibp.entity.IbpEventLogData;
import com.ibp.service.DictDataService;

/****
 * 
 * @author yf141
 * 日志读取
 *
 */
@Component
public class EventLogReader extends Thread implements InitializingBean {

	Logger logger = LoggerFactory.getLogger(EventLogReader.class);
	
	private String iblogCmd_ip ;
	private String iblogCmd_port ;
	
	private ServletContext servletContext;

	@Autowired
	DictDataService dictDataServiceImpl;
	@Autowired
	IbpEventLogDataMapper ibpEventLogDataMapper;
	
	@Override
	public void run(){

		Socket socket= null ;
		OutputStream os = null ;
		BufferedReader br = null ;
		
		try {
			logger.info("eventLog日志读取开始：");
			socket = new Socket(iblogCmd_ip,Integer.valueOf(iblogCmd_port));
			//socket.setSoTimeout(3000);
	        os = socket.getOutputStream() ;
	    	br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
	    	os.write("tail -F log/event.log \n".getBytes());
	    	os.flush();
	    	String str = null;
	    	while((str=br.readLine())!=null){
	    		IbpEventLogData elog = perseLogContext(str);
	    		if(elog.getDateTime() != null ){
	    			ibpEventLogDataMapper.add(elog);
	    		}
	    	}
		} catch (Exception e) {
			logger.error("日志读取线程出错："+ e);
		} 
        	
	}
	
	/***
	 * 解析日志内容，使用正则拆分字符串，如果原字符串第15列不是'|'则过滤掉
	 * @param str
	 * @throws ParseException 
	 */
	protected IbpEventLogData perseLogContext(String logStr){
		IbpEventLogData log = new IbpEventLogData();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
		String str = logStr.replaceAll("\\s", "\\]\\[");
		String[] alog = str.split("(\\]\\[)");
		if(alog.length>18 && "|".equals(alog[17])){
			log.setLogType("T");  //交易类型日志
			for(int i = 0 ;i < alog.length ; i++ ){
				String con = alog[i].replaceAll("[\\[\\]]", "") ;
				switch(i){
				    case 0 : 
				    	String date = alog[i] ;
				    	String[] array_date =  alog[i].split("\\-");
				    	log.setYmd(date);
						log.setYear(array_date[0]);
						log.setMonth(array_date[1]);
						log.setDay(array_date[2]);
					try {
						log.setWeek(this.getWeekOfYear(sdf1.parse(date)));
					} catch (ParseException e1) {
						logger.error("eventLog日期【时间】处理异常："+e1);
					}
				    	break; 
				    case 1 :
					try {
						String hms = alog[i] ;
						String[] array_hms = alog[i].split(":");
						log.setDateTime(sdf.parse(alog[0]+" "+alog[1])) ;
						log.setHms(hms);
						log.setHh(array_hms[0]);
						log.setMm(array_hms[1]);
						log.setM10(array_hms[1].substring(0, 1));
						log.setSs(array_hms[2]);
						log.setS10(array_hms[2].substring(0, 1));
					} catch (ParseException e) {
						logger.error("eventLog日期【时间】处理异常："+e);
					} break;
					case 3 :
						log.setLogLevel(con);
						break ;
					case 5 :
						log.setProcessName(con);
						break ;
					case 7 :
						log.setProcessId(con);
						break ;
					case 9 :
						log.setClinetNodeName(con);
						break ;
					case 10 :
						log.setClinetNodeAddress(con);
						break;
					case 12 :
						log.setServerNodeName(con);
						break ;
					case 13 :
						log.setServerNodeAddress(con);
						break ;
					case 14 :
						log.setTradeCode(con);
						break ;
					case 15 :
						log.setTradeDescribe(con);
						break ;
					case 16 :
						log.setCommunicateResponseCode(con);
						break ;
					case 18 :
						log.setTradeTotalTime(new BigDecimal(con));
						break ;
					case 19 :
						log.setTradeKeepTime(new BigDecimal(con));
						break ;
					case 20 :
						log.setCommunicateReceiveTime(new BigDecimal(con));
						break ;
					case 21 :
						log.setAppcationProcessTime(new BigDecimal(con));
						break ;
					case 22 :
						log.setCommunicateSendTime(new BigDecimal(con));
						break ;
					case 23 :
						log.setTradeProcessTime(new BigDecimal(con));
						break ;
				}
			}
		}else{ 
			
			log.setLogType("O");  //其他类型日志
			
			for(int i = 0 ;i < alog.length ; i++ ){
				String con = alog[i].replaceAll("[\\[\\]]", "") ;
				switch(i){
			    case 0 : 
			    	String date = alog[i] ;
			    	String[] array_date =  alog[i].split("\\-");
			    	log.setYmd(date);
					log.setYear(array_date[0]);
					log.setMonth(array_date[1]);
					log.setDay(array_date[2]);
				try {
					log.setWeek(this.getWeekOfYear(sdf1.parse(date)));
				} catch (ParseException e1) {
					logger.error("eventLog日期【时间】处理异常："+e1);
				}
			    	break; 
			    case 1 :
				try {
					String hms = alog[i] ;
					String[] array_hms = alog[i].split(":");
					log.setDateTime(sdf.parse(alog[0]+" "+alog[1])) ;
					log.setHms(hms);
					log.setHh(array_hms[0]);
					log.setMm(array_hms[1]);
					log.setM10(array_hms[1].substring(0, 1));
					log.setSs(array_hms[2]);
					log.setS10(array_hms[2].substring(0, 1));
				} catch (ParseException e) {
					logger.error("eventLog日期【时间】处理异常："+e);
				} break;
					case 3 :
						log.setLogLevel(con);
						break ;
					case 5 :
						log.setProcessName(con);
						break ;
					case 7 :
						log.setProcessId(con);
						break ;
				}	
			}
			//日志未分割字符串
			String[] logInfo = logStr.split("\\|");
			if(logInfo != null && logInfo.length>=5){
				log.setLogInfo(logInfo[4]);
			}
		}
		
		return log ;
	}

	/***
	 * 当前日期为本年的第几周
	 * @param date
	 * @return
	 */
	private String getWeekOfYear(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		return String.valueOf(calendar.get(calendar.WEEK_OF_YEAR));
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void afterPropertiesSet() throws Exception {
	  	this.servletContext = dictDataServiceImpl.getServletContext();
	  	logger.info("初始化ExecuteCmdServiceImpl服务节点ip和port配置,servletContext:"+servletContext); 
	    Map<String,Map<String,String>> dictMap = (Map<String, Map<String, String>>) this.servletContext.getAttribute("dictMap");
	    
	    this.iblogCmd_ip = 	 dictMap.get("tcp.iblog").get("ip");
		this.iblogCmd_port = dictMap.get("tcp.iblog").get("port") ;
		
		logger.info("eventLog日志内容读取线程启动:");
		//this.start();
		
	}
	
}
